package m.store.service;

import m.base.model.StoreInfo;
import m.base.model.UserInfo;
import m.base.util.PowerUtil;
import m.common.model.util.*;
import m.common.service.Service;
import m.store.model.*;
import m.store.task.GuestStockSupport;
import m.store.task.MonthRecordSupport;
import m.store.task.StockInfoPaySupport;
import m.system.exception.MException;
import m.system.util.ArrayUtil;
import m.system.util.GenerateID;
import m.system.util.NumberUtil;
import m.system.util.ObjectUtil;

import java.util.*;

public class PayAmountService extends Service {
    public String save(PayAmount model, List<PayAmountRecord> stockList) throws Exception {
        if(null==stockList||stockList.isEmpty()) throw new MException(this.getClass(),"请添加入库订单");
        ModelQueryCheck.init(model)
            .checkNotNull("guest.oid","请选择付款客户")
            .checkNotNull("payDate","付款日期不能为空")
            .checkNotNull("status","状态错误")
            .checkStrEq("status",OrderModel.Status_Register,"登记状态才能修改")
            .doCheck(false,true);
        PowerUtil.verifyAccountDate(model.getPayDate(),"付款日期");
        String msg="";
        if(ObjectUtil.isEmptyOid(model)){
            model.setOid(GenerateID.generatePrimaryKey());
            ModelUpdateUtil.insertModel(model);
            msg="保存成功";
        }else{
            ModelUpdateUtil.updateModel(model,"guest.oid","payDate","remark");
            msg="修改成功";
        }
        ModelUpdateUtil.delete(PayAmountRecord.class, QueryCondition.eq("pay.oid",model.getOid()));
        StockInfoService stockService=getService(StockInfoService.class);
        Map<String,Double> amountMap=new HashMap<>();
        Set<String> error=new HashSet<>();
        for(PayAmountRecord record : stockList){
            ModelQueryCheck.init(record)
                .checkNotNull("stock.oid","请选择入库订单")
                .checkNotNull("payAmount","请输入付款金额")
                .doCheck(false,true);
            String stockOid=record.getStock().getOid();
            stockService.updateInPayAmount(stockOid);
            StockInfo stock=ModelQueryList.getModel(record.getStock());
            if(null!=amountMap.get(stockOid)) throw new MException(this.getClass(),stock.getOrderNo()+" 重复添加了");
            amountMap.merge(stockOid, record.getPayAmount(), Double::sum);//累加相同商品数量
            if(NumberUtil.round(stock.getOweAmount()-stock.getInPayAmount()-amountMap.get(stockOid),2)<0)
                error.add(stock.getOrderNo());
            record.setOid(GenerateID.generatePrimaryKey());
            record.setPay(model);
        }
        if(!error.isEmpty()) //付款已超出
            throw new MException(this.getClass(),"付款已超出 - "+ ArrayUtil.connection(error.toArray(),","));
        ModelUpdateUtil.insertModels(stockList.toArray(new PayAmountRecord[0]));
        updateAmount(model.getOid());
        return msg;
    }
    private void updateAmount(String oid) throws MException {
        ModelUpdate.init(PayAmount.class)
            .set("payAmount",PayAmountRecord.class,"ifnull(sum(#{payAmount}),0)",QueryCondition.eq("pay.oid",oid))
            .execute(oid);
    }

    /**
     * 提交
     */
    public void saveAndSubmit(PayAmount model, List<PayAmountRecord> stockList) throws Exception {
        save(model,stockList);
        model.setStatus(OrderModel.Status_Check);
        model.setSubmitDate(new Date());
        ModelUpdateUtil.updateModel(model,"status","submitDate");
    }

    /**
     * 删除
     */
    public void delete(String oid, UserInfo user) throws Exception {
        PayAmount model=ModelQueryList.getModel(PayAmount.class,oid,"*");
        ModelQueryCheck.init(model)
            .checkStrEq("status",OrderModel.Status_Register,"登记中才能删除")
            .checkStrEq("inputUser.oid",user.getOid(),"权限错误")
            .doCheck(false,true);
        ModelUpdateUtil.deleteModel(model);
        ModelUpdateUtil.delete(PayAmountRecord.class, QueryCondition.eq("stock.oid",model.getOid()));
    }

    /**
     * 审核通过
     */
    public void check(String oid,Date payDate,String remark, StoreInfo store,UserInfo user) throws Exception {
        PayAmount model=ModelQueryList.getModel(PayAmount.class,oid,"*");
        model.setPayDate(payDate);
        model.setRemark(remark);
        ModelQueryCheck.init(model)
            .checkNotNull("payDate","付款日期不能为空")
            .checkStrEq("status",OrderModel.Status_Check,"审核中才能通过")
            .checkStrEq("store.oid",store.getOid(),"权限错误")
            .doCheck(false,true);
        PowerUtil.verifyAccountDate(model.getPayDate(),"付款日期");
        model.setStatus(OrderModel.Status_Done);
        model.setCheckUser(user);
        model.setCheckDate(new Date());
        ModelUpdateUtil.updateModel(model,"status","checkUser.oid","checkDate","payDate","remark");
        //关联到款金额
        getService(GuestBackAmountService.class).linkAmount(model);
        //更新库存付款信息
        ModelQueryList.getModelList(PayAmountRecord.class,
            new String[]{"stock.oid"},null,
            QueryCondition.eq("pay.oid",model.getOid())
        ).forEach(item-> StockInfoPaySupport.add(item.getStock().getOid()));
        StockInfoPaySupport.start();
        //更新客户付款金额
        GuestStockSupport.add(model.getGuest().getOid());
        GuestStockSupport.start();
        //更新月度统计
        MonthRecordSupport.add(model.getInputUser().getOid(),model.getPayDate(),MonthRecord.Type_Pay);
        MonthRecordSupport.start();
    }

    /**
     * 退回
     */
    public void refund(String oid, StoreInfo store,UserInfo user) throws Exception {
        PayAmount model=ModelQueryList.getModel(PayAmount.class,oid,"*");
        ModelQueryCheck.init(model)
            .checkStrEq("status",OrderModel.Status_Check,"审核中才能退回")
            .checkStrEq("store.oid",store.getOid(),"权限错误")
            .doCheck(false,true);
        model.setStatus(OrderModel.Status_Register);
        model.setCheckUser(user);
        model.setCheckDate(new Date());
        ModelUpdateUtil.updateModel(model,"status","checkUser.oid","checkDate");
    }
}
